/*
 * This class wraps URLLoader with an interface similar to the php HTTP_Request function
 * written for PHPTube port - implementation is only partial with no real reference to the original HTTP_Request.php class ^_^ 
 * http://pear.php.net/package/HTTP_Request (deprecated anyway, lols)
 * It is adapted from the example code on adobe LiveDocs: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/
 * Gareth Williams
 */

package com.gw.youTubeAudioAPI.phpTube.HTTP_Request 
{
	import flash.events.*;
	import flash.net.*;
	
    public class HTTP_Request extends EventDispatcher
	{
		private var _responseBody:*;	//actual data
		private var _response:Response;		//error handling
		private var loader:URLLoader = new URLLoader();
		private var request:URLRequest;
		
		public static const HTTP_REQUEST_METHOD_GET:String	= URLRequestMethod.GET; 
		public static const HTTP_REQUEST_METHOD_POST:String	= URLRequestMethod.POST; 
		
		public static const HTTP_REQUEST_TYPE_BIN:String	= URLLoaderDataFormat.BINARY;
		public static const HTTP_REQUEST_TYPE_STRING:String	= URLLoaderDataFormat.TEXT;
		public static const HTTP_REQUEST_TYPE_VAR:String	= URLLoaderDataFormat.VARIABLES;
		
        public function HTTP_Request(url:String, rest:Object = null)//php does not support ...rest parameter 
		{
			super();
			
			request = new URLRequest(url);//defualt data format is string
			if (rest) //parse parameters and configure urlrequest
			{
				for (var p:String in rest) {
					switch (p) {
						case "type":
						{	
							loader.dataFormat = rest[p];//if non standard format is requested URLRequest will throw error
							break;
						}
						case "allowRedirects":
						{	
							request.followRedirects = rest[p];
							break;
						}
						case "maxRedirects":
						{
							//not supported / required by urlRequest
							break;
						}
						default:
						{	
							throw new Error("unsupported parameter: "+p+" in HTTP_Request constructor");
							break;
						}
					}
				}
			}
			configureListeners(loader);
        }
        private function configureListeners(dispatcher:IEventDispatcher):void 
		{
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
            dispatcher.addEventListener(Event.OPEN, openHandler);
            dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            dispatcher.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
        }
        private function completeHandler(event:Event):void 
		{
			_responseBody = loader.data;
			//pass on event
			this.dispatchEvent(new Event(Event.COMPLETE));
        }
        private function openHandler(event:Event):void 
		{
            trace("openHandler: " + event);
        }
        private function progressHandler(event:ProgressEvent):void 
		{
            trace("progressHandler loaded:" + event.bytesLoaded + " total: " + event.bytesTotal);
        }
        private function httpStatusHandler(event:HTTPStatusEvent):void 
		{
            trace("httpStatusHandler: " + event);
        }
        //TODO:wrap these
		private function ioErrorHandler(event:IOErrorEvent):void 
		{
            trace("ioErrorHandler: " + event);
        }
		private function securityErrorHandler(event:SecurityErrorEvent):void 
		{
			trace("securityErrorHandler: " + event);
        }
		//interface
		public function sendRequest():Object 
		{
			_responseBody = new Response();
			try 
			{
				loader.load(request);
            } 
			catch (error:Error) 
			{
				_responseBody.message = error.message;
            }
			return _responseBody;
		}
		//non standard getter and setter methods used to match original php interface
		public function getResponseBody():Object 
		{
			return _responseBody;
		}
		public function setMethod(method:String):void 
		{
			request.method = method; //URLloader will throw an error if this is not defined by one of the constants so we don't need to validate here
		}
		public function addHeader(parameter:String, value:*):void 
		{
			request.requestHeaders.push(new URLRequestHeader(parameter, value));
		}
    }
}
internal class Response //helper class basically for error handling
{
	private var _message:String;
	private var _isError:Boolean = false;
	
	public function Response():void 
	{
		//default constructor
	}
	public function set message(message:String):void 
	{
		this._message = message;
		this._isError = true;
	}
	public function getMessage():String //non standard getter used to match original php interface
	{
		return _message;
	}
	public function get isError():Boolean
	{
		return _isError; //read only
	}
}